import {
  Injectable,
  CanActivate,
  HttpException,
  HttpStatus,
  ExecutionContext,
  Logger,
} from "@nestjs/common";
import { AuthService } from "../auth/auth.service";
import { serverConfig } from "./config";
@Injectable()
export class AuthGuard implements CanActivate {
  constructor(private authService: AuthService) {}

  // context 请求的(Response/Request)的引用
  async canActivate(context: ExecutionContext): Promise<boolean> {
    console.log("进入全局权限守卫...");
    // 获取请求对象
    const request = context.switchToHttp().getRequest();
    // 获取请求头中的token字段
    const token = context.switchToRpc().getData().headers.token;
    // 如果白名单内的路由就不拦截直接通过
    if (this.hasUrl(this.urlList, request.url)) {
      // if (token) { //白名单的不验证token
      //   return this.ParsingTokens(token, request);
      // }
      return true;
    }
    // 验证token的合理性以及根据token做出相应的操作
    if (token) {
      return this.ParsingTokens(token, request);
    } else {
      this.HttpExceptionFun();
    }
  }
  // 白名单数组
  private urlList: string[] = serverConfig.NotinterfaceList;

  //如果有token解析token
  private ParsingTokens(token: any, request: any) {
    Logger.log(" guth 日志 开始", JSON.stringify(token), " token ");
    try {
      let decoded = this.authService.validateToken(token);
      if (!decoded) {
        this.HttpExceptionFun();
      }
      request.user = decoded;
      return true;
    } catch (e) {
      Logger.log(" guth 日志 结束", JSON.stringify(e), " token ");
      this.HttpExceptionFun();
    }
  }

  private HttpExceptionFun() {
    throw new HttpException("没有授权访问,请先登录", HttpStatus.UNAUTHORIZED);
  }

  // 验证该次请求是否为白名单内的路由
  private hasUrl(urlList: string[], url: string): boolean {
    let flag: boolean = false;
    const newUrl = this.extractApiPath(url);
    if (urlList.indexOf(newUrl) >= 0) {
      flag = true;
    }
    return flag;
  }

  private extractApiPath(url: string) {
    const questionMarkIndex = url.indexOf("?");
    if (questionMarkIndex !== -1) {
      return url.slice(0, questionMarkIndex);
    }
    return url;
  }
}
